#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "load.h"

int main (int argc, char * argv[]) {
	if (argc != 2) {
		printf("Mauvais nombre d'arguments.\n");
		return 0;
	} 
	if (!estELF(argv[1])) {
		printf("Le fichier en argument doit être un .o\n");
		return 0;
	}
	int i, j=0;
	FILE * f = fopen(argv[1], "r");
	Elf32_Ehdr header = load_header(f);
	Elf32_Shdr* sheader = NULL;
	sheader = load_section_headers(f);
	char name[50];
	char c;
	int deb =0;
	fseek (f ,header.e_shoff + (header.e_shentsize * header.e_shstrndx) +16, SEEK_SET);
	fread(&deb, 1, 4, f);
	if (sheader == NULL) {
		printf("Erreur d'allocation !\n");
		return 0;
	}
	printf("Section Headers :\n  %-3s %-20s %-13s %-8s %-6s %-6s %-2s %-4s %-1s %-1s%-1s  \n", "Nr", "Nom", "Type", "Addr", "Off", "Taille", "ES", "Flg", "Lk", "Inf", "Al");
	for (i = 0; i < header.e_shnum; i++) {
		//NAME
		fseek (f ,deb + sheader[i].sh_name , SEEK_SET);
		c = (char)fgetc(f);
		while (c != '\0') {
			name[j] = c;
			c = (char)fgetc(f);
			j++;
		}
		name[j] = c;
		printf("  %-3d %-20s",i, name);
		j =0;
		//TYPE
		switch(sheader[i].sh_type) {
		case 0:
			printf("%-13s","NULL");
			break;
		case 1:
			printf("%-13s","PROGBITS");
			break;
		case 2:
			printf("%-13s","SYMTAB");
			break;
		case 3:
			printf("%-13s","STRTAB");
			break;
		case 4:
			printf("%-13s","RELA");
			break;
		case 5:
			printf("%-13s","HASH");
			break;
		case 6:
			printf("%-13s","DYNAMIC");
			break;
		case 7:
			printf("%-13s","NOTE");
			break;
		case 8:
			printf("%-13s","NOBITS");
			break;
		case 9:
			printf("%-13s","REL");
			break;
		case 10:
			printf("%-13s","SHLIB");
			break;
		case 11:
			printf("%-13s","DYNSYM");
			break;
		case 0x70000000:
			printf("%-13s","LOPROC");
			break;
		case 0x7fffffff:
			printf("%-13s","HIPROC");
			break;
		case 0x80000000:
			printf("%-13s","LOUSER");
			break;
		case 0xffffffff:
			printf("%-13s","HIUSER");
			break;
		case 0x70000003:
			printf("%-13s","ARM");
			break;
		default: 
			printf("%-13s","  ");
			break;		
		}
		
		//ADDR OFF SIZE ES
		printf("%-8lx  %-6lx  %-6lx  %-2lx ", sheader[i].sh_addr, sheader[i].sh_offset, sheader[i].sh_size, sheader[i].sh_entsize);

		//FLAG
		if (sheader[i].sh_flags & 1) {
			printf("%1s", "W");
		} else {
			printf("%1s"," ");
		}
		if (sheader[i].sh_flags & 2) {
			printf("%1s","A");
		} else {
			printf("%1s"," ");
		}
		if (sheader[i].sh_flags & 4) {
			printf("%1s","X");
		} else {
			printf("%1s"," ");
		}
		if (sheader[i].sh_flags & 0xf0000000) {
			printf("%1s","M");
		} else {
			printf("%1s"," ");
		}
		//LINK INF AL
		printf("%-1lx  %-1lx  %-1lx \n",sheader[i].sh_link, sheader[i].sh_info, sheader[i].sh_addralign);
	}

	free(sheader);
	return 0;
}

